package com.wudimeng.syll.utils;

import com.google.common.base.Optional;

import java.math.BigDecimal;

/**
 * 名称: 工具类 描述: 费用计算工具类
 */
public class NumberUtil {
	//Integer加法运算的封装
    public static Integer safeAdd(Integer b1, Integer... bn) {
        if (null == b1) {
            b1 = 0;
        }
        Integer r = b1;
        if (null != bn) {
            for (Integer b : bn) {
                r += Optional.fromNullable(b).or(0);
            }
        }
        return r > 0 ? r : 0;
    }


    //整型的减法运算，小于0时返回0
    public static Integer safeSubtract(Integer b1, Integer... bn) {
        if (null == b1) {
            b1 = 0;
        }
        Integer r = b1;
        if (null != bn) {
            for (Integer b : bn) {
                r -= Optional.fromNullable(b).or(0);
            }
        }
        return null != r && r > 0 ? r : 0;
    }

    //BigDecimal强转
    public static BigDecimal safeBigDecimal(Object b1) {
        if (null == b1 || "".equals(b1)) {
            b1 = BigDecimal.ZERO;
        }

        return new BigDecimal(b1.toString());
    }

    //BigDecimal的加法运算封装
    public static BigDecimal safeAdd(BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        if (null != bn) {
            for (BigDecimal b : bn) {
                b1 = b1.add(null == b ? BigDecimal.ZERO : b);
            }
        }
        return b1;
    }


    //计算金额方法
    public static BigDecimal safeSubtract(BigDecimal b1, BigDecimal... bn) {
        return safeSubtract(true, b1, bn);
    }

    /**
     * BigDecimal的安全减法运算
     *
     * @param isZero 减法结果为负数时是否返回0，true是返回0（金额计算时使用），false是返回负数结果
     * @param b1     被减数
     * @param bn     需要减的减数数组
     * @return
     */
    public static BigDecimal safeSubtract(Boolean isZero, BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        BigDecimal r = b1;
        if (null != bn) {
            for (BigDecimal b : bn) {
                r = r.subtract((null == b ? BigDecimal.ZERO : b));
            }
        }
        return isZero ? (r.compareTo(BigDecimal.ZERO) == -1 ? BigDecimal.ZERO : r) : r;
    }

    //金额除法计算，返回2位小数
    public static <T extends Number> BigDecimal safeDivide(T b1, T b2) {
        return safeDivide(b1, b2, BigDecimal.ZERO);
    }

    /**
     * BigDecimal的除法运算封装，如果除数或者被除数为0，返回默认值
     * 默认返回小数位后2位，用于金额计算
     */
    public static <T extends Number> BigDecimal safeDivide(T b1, T b2, BigDecimal defaultValue) {
        if (null == b1 || null == b2) {
            return defaultValue;
        }
        try {
            return BigDecimal.valueOf(b1.doubleValue()).divide(BigDecimal.valueOf(b2.doubleValue()), 0, BigDecimal.ROUND_UP);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * BigDecimal的乘法运算封装 向上取整
     */
    public static <T extends Number> BigDecimal safeMultiply(T b1, T b2) {
        if (null == b1 || null == b2) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(b1.doubleValue()).multiply(BigDecimal.valueOf(b2.doubleValue())).setScale(0, BigDecimal.ROUND_UP);
    }

    /**
     * BigDecimal的乘法运算封装 向下取整
     */
    public static <T extends Number> BigDecimal safeMultiplyDown(T b1, T b2) {
        if (null == b1 || null == b2) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(b1.doubleValue()).multiply(BigDecimal.valueOf(b2.doubleValue())).setScale(0, BigDecimal.ROUND_DOWN);
    }

    //随机生成狮兔牌
    public static String generateRandomCode(){
        //定义匹配3位以上的重复数字
        String regex = "([\\d])\\1{2,}";
        //定义匹配4-9位连续的数字
        String regex2 = "(?:(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){5}|(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){5})\\d";
        String str = "0";
        for (int i = 0; i <= 10; i++)
        {
            int intFlag = (int)(Math.random() * 10000000);
            String flag = String.valueOf(intFlag);
            if (flag.length() == 7 && !flag.substring(0, 1).equals("0") && !flag.matches(regex) && !flag.matches(regex2)) {
                str =  flag;
                break;
            }
        }
        return str;
    }


    public static void main(String[] a) {
        System.out.println(safeMultiply(12,0.006));
        System.out.println(safeAdd(12,2));
        System.out.println(safeDivide(12,5));

//        System.out.println(safeBigDecimal("-adsf"));
    }
}
